﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using SharpPcap;
using SharpPcap.WinPcap;
using SharpPcap.AirPcap;
using SharpPcap.LibPcap;
using System.Threading;
using PacketDotNet;
namespace winfm1
{
    struct StrPackage
    {
       
        public DateTime Time;
        //public string Source;
        //public string Destination;
        public ushort SourcePort;
        public ushort DesPort;
        public int Length;
        public Packet Packet;
        //public MyEthernetPacket ePacket;
        public MyIpPacket ipPacket;
        public MyTCPPacket tcpPacket;
        public MyUDPPacket udpPacket;
        public string Protocols;
    }
    public partial class Form1 : Form
    {
        bool isRun = false;
        object objLock = new object();
        int iPackageCount=0;
        ClsPackageCache clsPkgCache = new ClsPackageCache();
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (comboBox1.SelectedItem!=null)
            {
                ICaptureDevice Dev = ((ClsComboboxItem)comboBox1.SelectedItem).Value;
                Dev.OnPacketArrival += new PacketArrivalEventHandler(Dev_OnPacketArrival);
                Dev.Open(DeviceMode.Promiscuous);
               // Dev.Filter = tstxtFilter.Text;
                Dev.StartCapture();
                isRun = true;
                backgroundWorker1.RunWorkerAsync();
            }
        }

        private void Dev_OnPacketArrival(object sender, CaptureEventArgs e)
        {
          //  throw new NotImplementedException();
           
                clsPkgCache.AddItem(e.Packet);
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            CaptureDeviceList deviceLst = CaptureDeviceList.Instance;
            foreach (ICaptureDevice dev in deviceLst)
            {
                if (dev is AirPcapDevice)
                {
                    richTextBox1.Text += dev.ToString();
                }
                else if (dev is WinPcapDevice)
                {
                    ClsComboboxItem clsCbxItem = new ClsComboboxItem();
                    clsCbxItem.Text = ((WinPcapDevice)dev).Interface.FriendlyName + "  " + dev.Description.Split('\'')[1];
                    clsCbxItem.Value = dev;
                    comboBox1.Items.Add(clsCbxItem);
                    //Cl clsCbxItem = new ClsComboboxItem();
                    //clsCbxItem.Text = ((WinPcapDevice)dev).Interface.FriendlyName + "  " + dev.Description.Split('\'')[1];
                    //clsCbxItem.Value = dev;
                    //tscbxDeviceLst.ComboBox.Items.Add(clsCbxItem);
                    richTextBox1.Text += ((WinPcapDevice)dev).Interface.FriendlyName + "  " + dev.Description.Split('\'')[1]+dev.ToString();
                }
                else if (dev is LibPcapLiveDevice)
                {
               richTextBox1.Text += dev.ToString();
                }
            }
        }
        void PackageAna()
        {
            RawCapture rawCapture = clsPkgCache.GetAndRemoveFrist();
            if (rawCapture == null)
                return;

            iPackageCount++;
            StrPackage strPackage = new StrPackage();

            strPackage.Time = rawCapture.Timeval.Date.ToLocalTime();
            strPackage.Length = rawCapture.Data.Length;

            PacketDotNet.Packet tempPacket = PacketDotNet.Packet.ParsePacket(rawCapture.LinkLayerType, rawCapture.Data);
            strPackage.Packet = tempPacket;

            //PacketDotNet.EthernetPacket ePacket = (PacketDotNet.EthernetPacket)PacketDotNet.EthernetPacket.ParsePacket(rawCapture.LinkLayerType, rawCapture.Data);   
            //if (ePacket != null)
            //{
            //    strPackage.ePacket = new MyEthernetPacket(ePacket);
            //    strPackage.Protocols += ePacket.Type.ToString() + "| ";

            //    //CrossSetDataTable(iPackageCount, strPackage.Time, ePacket.SourceHwAddress.ToString(), ePacket.DestinationHwAddress.ToString(), ePacket.Type.ToString());
            //}

            IpPacket ipPack = PacketDotNet.IpPacket.GetEncapsulated(tempPacket);
            if (ipPack != null)
            {
                strPackage.Protocols += ipPack.Protocol.ToString() + "| ";
                strPackage.ipPacket = new MyIpPacket(ipPack);

                if (ipPack.Protocol.ToString() == "TCP")
                {
                    PacketDotNet.TcpPacket tcppacket = TcpPacket.GetEncapsulated(tempPacket);
                    if (tcppacket != null)
                    {
                        strPackage.tcpPacket = new MyTCPPacket(tcppacket);
                        strPackage.SourcePort = tcppacket.SourcePort;           // 80, 8080, 3128: Http; 21: FTP; 25: SMTP; 110: POP3
                        strPackage.DesPort = tcppacket.DestinationPort;
                    }

                }
                else if (ipPack.Protocol.ToString() == "UDP")
                {
                    PacketDotNet.UdpPacket udppacket = UdpPacket.GetEncapsulated(tempPacket);
                    if (udppacket != null)
                    {
                        strPackage.udpPacket = new MyUDPPacket(udppacket);
                        strPackage.SourcePort = udppacket.SourcePort;           // 53: DNS
                        strPackage.DesPort = udppacket.DestinationPort;
                    }
                }

                //CrossSetDataTable(iPackageCount, strPackage.Time, ipPack.SourceAddress.ToString(), strPackage.SourcePort,
              //      ipPack.DestinationAddress.ToString(), strPackage.DesPort, ipPack.Protocol.ToString());
             //   lstPackage.Add(iPackageCount, strPackage);
                this.Invoke(new getdg(this.showdata), new object[] { iPackageCount, strPackage.Time, ipPack.SourceAddress.ToString(), strPackage.SourcePort, ipPack.DestinationAddress.ToString(), strPackage.DesPort, ipPack.Protocol.ToString(),strhb(strPackage.Packet.Bytes.Select(h=>h.ToString()).ToArray()) });
                
            }
        }
        private string strhb(string[] s)
        {
            string p = "";
            foreach (string f in s)
            {
             p+=f;
            }
            return p;
        }
        private delegate void getdg(int Sqe, DateTime Time, string Source, ushort SourcePort, string Destination, ushort DesPort, string Protocol,string bs);
         private void showdata(int Sqe, DateTime Time, string Source, ushort SourcePort, string Destination, ushort DesPort, string Protocol,string bs )
        {
            richTextBox1.Text +=Sqe.ToString()+"时间"+ Time.ToString()+"来源ip"+Source.ToString()+"端口"+SourcePort.ToString()+"目的ip"+ Destination.ToString()+"端口"+ DesPort.ToString()+"协议"+Protocol.ToString()+"内容"+bs;
        }
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            while (isRun || clsPkgCache.GetCount() > 0)
            {
                PackageAna();
                Thread.Sleep(50);
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
